summaryrefslogtreecommitdiffstats
path: root/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
blob: a16ca85290f3f16a7e42f223c22bf700bc2bcb89 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

package org.yuzu.yuzu_emu.ui.main

import android.os.Bundle
import android.view.View
import android.view.ViewGroup.MarginLayoutParams
import android.view.animation.PathInterpolator
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.color.MaterialColors
import com.google.android.material.elevation.ElevationOverlayProvider
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.activities.EmulationActivity
import org.yuzu.yuzu_emu.databinding.ActivityMainBinding
import org.yuzu.yuzu_emu.model.HomeViewModel
import org.yuzu.yuzu_emu.utils.*

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    private val homeViewModel: HomeViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        val splashScreen = installSplashScreen()
        splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }

        ThemeHelper.setTheme(this)

        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        WindowCompat.setDecorFitsSystemWindows(window, false)

        ThemeHelper.setNavigationBarColor(
            this,
            ElevationOverlayProvider(binding.navigationBar.context).compositeOverlay(
                MaterialColors.getColor(binding.navigationBar, R.attr.colorSurface),
                binding.navigationBar.elevation
            )
        )

        // Set up a central host fragment that is controlled via bottom navigation with xml navigation
        val navHostFragment =
            supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
        binding.navigationBar.setupWithNavController(navHostFragment.navController)

        binding.statusBarShade.setBackgroundColor(
            ThemeHelper.getColorWithOpacity(
                MaterialColors.getColor(
                    binding.root,
                    R.attr.colorSurface
                ), ThemeHelper.SYSTEM_BAR_ALPHA
            )
        )

        // Prevents navigation from being drawn for a short time on recreation if set to hidden
        if (homeViewModel.navigationVisible.value == false) {
            binding.navigationBar.visibility = View.INVISIBLE
            binding.statusBarShade.visibility = View.INVISIBLE
        }

        homeViewModel.navigationVisible.observe(this) { visible ->
            showNavigation(visible)
        }

        // Dismiss previous notifications (should not happen unless a crash occurred)
        EmulationActivity.tryDismissRunningNotification(this)

        setInsets()
    }

    private fun showNavigation(visible: Boolean) {
        binding.navigationBar.animate().apply {
            if (visible) {
                binding.navigationBar.visibility = View.VISIBLE
                binding.navigationBar.translationY = binding.navigationBar.height.toFloat() * 2
                duration = 300
                translationY(0f)
                interpolator = PathInterpolator(0.05f, 0.7f, 0.1f, 1f)
            } else {
                duration = 300
                translationY(binding.navigationBar.height.toFloat() * 2)
                interpolator = PathInterpolator(0.3f, 0f, 0.8f, 0.15f)
            }
        }.withEndAction {
            if (!visible) {
                binding.navigationBar.visibility = View.INVISIBLE
            }
        }.start()
    }

    override fun onDestroy() {
        EmulationActivity.tryDismissRunningNotification(this)
        super.onDestroy()
    }

    private fun setInsets() =
        ViewCompat.setOnApplyWindowInsetsListener(binding.statusBarShade) { view: View, windowInsets: WindowInsetsCompat ->
            val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
            val mlpShade = view.layoutParams as MarginLayoutParams
            mlpShade.height = insets.top
            binding.statusBarShade.layoutParams = mlpShade
            windowInsets
        }
}